#include "DataStructures/Molecule.h"
#include <iostream>
#include <functional>
#include <dlfcn.h>
#include "computations/permutations.h"

using namespace OpenBabel;
using namespace std;

/**
 * Read a molecule from a file file
 *
 * @param filename The file name to read from
 * @param format   The file format in Open Babel terms (if NULL is given, attempt to get format
 * 	  from the suffix)
 * @param babelBond Should the convertor let openbabel choose bonding
 * @return The OBMol read from the file
 */
OBMol* readMolecule (char *filename) {
	OBMol* mol = new OBMol();
	OBConversion conv;
	OBFormat* f = OBConversion::FormatFromExt(filename);
	const char *format;
	if (f == NULL) {
		printf("Error discovering format from filename %s\n", filename);
		exit(1);
	}
	format = OBConversion::FormatFromExt(filename)->GetType().name();
	if (!conv.SetInFormat(OBConversion::FormatFromExt(filename))) {
		printf ("Error setting input format to %s\n", format);
		exit(1);
	}
	if (!conv.ReadFile(mol, filename)) {
		printf ("Error reading file %s using OpenBabel with format %s\n", filename, format);
		exit(1);
	}
	return mol;
}

int main(int argc, char *argv[])
{
	OBMol* babmol = readMolecule(argv[1]);
	Molecule mol(*babmol);
	mol.printAtoms();
	cout << "loading library basic" << endl;
	void* libbasic = dlopen("bin/computations/libbasic.so", RTLD_LAZY);
	if (!libbasic)
	{
		cout << "couldn't load library: " << dlerror() << endl;
		exit(1);
	}
	void (*test)(Molecule&) = (void (*)(Molecule&)) dlsym(libbasic,"printClasses");
	char * error = dlerror();
	if (error != NULL)
	{
		{
			cout << "couldn't find symbol: " << error << endl;
			exit(1);
		}
	}
	(*test)(mol);
	delete(babmol);
	cout << "loading library permutations" << endl;
	void* libper = dlopen("bin/computations/libpermutations.so", RTLD_LAZY);
	if (!libper)
	{
		cout << "couldn't load library: " << dlerror() << endl;
		exit(1);
	}
	int (*printPerms)(int, int, std::function<int (permutation*)>) = (int (*)(int, int, std::function<int (permutation*)>)) dlsym(libper,"find_all_cycles");
	error = dlerror();
	if (error != NULL)
	{
		{
			cout << "couldn't find symbol: " << error << endl;
			exit(1);
		}
	}
	int a = (*printPerms)(7,3,printPermutation);
	cout << "found " << a << " permutations" << endl;
	return 0;
}
